﻿using ProtoBuf;

namespace DHTools
{
    [ProtoContract]
    public class XVector3
    {
        [ProtoMember(1)]
        public float x;

        [ProtoMember(2)]
        public float y;

        [ProtoMember(3)]
        public float z;

        public float this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return x;

                    case 1:
                        return y;

                    case 2:
                        return z;

                    default:
                        throw new IndexOutOfRangeException("Invalid Vector3 index!");
                }
            }
            set
            {
                switch (index)
                {
                    case 0:
                        x = value;
                        break;

                    case 1:
                        y = value;
                        break;

                    case 2:
                        z = value;
                        break;

                    default:
                        throw new IndexOutOfRangeException("Invalid Vector3 index!");
                }
            }
        }
    }

    [ProtoContract]
    public class XVector4
    {
        [ProtoMember(1)]
        public float x;

        [ProtoMember(2)]
        public float y;

        [ProtoMember(3)]
        public float z;

        [ProtoMember(4)]
        public float w;
    }

    [ProtoContract]
    public class XQuaternion
    {
        [ProtoMember(1)]
        public float x;

        [ProtoMember(2)]
        public float y;

        [ProtoMember(3)]
        public float z;

        [ProtoMember(4)]
        public float w;

        public float this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return x;

                    case 1:
                        return y;

                    case 2:
                        return z;

                    case 3:
                        return w;

                    default:
                        throw new IndexOutOfRangeException("Invalid Vector3 index!");
                }
            }
            set
            {
                switch (index)
                {
                    case 0:
                        x = value;
                        break;

                    case 1:
                        y = value;
                        break;

                    case 2:
                        z = value;
                        break;

                    case 3:
                        w = value;
                        break;

                    default:
                        throw new IndexOutOfRangeException("Invalid Vector3 index!");
                }
            }
        }
    }

    [ProtoContract]
    public class XScaleTransform
    {
        [ProtoMember(1)]
        public XQuaternion rotation;

        [ProtoMember(2)]
        public XVector3 scale;

        [ProtoMember(3)]
        public XVector3 position;
        internal XQuaternion Rotation;

        public float this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0: return rotation.x;
                    case 1: return rotation.y;
                    case 2: return rotation.z;
                    case 3: return rotation.w;
                    case 4: return scale.x;
                    case 5: return scale.y;
                    case 6: return scale.z;
                    case 7: return position.x;
                    case 8: return position.y;
                    case 9: return position.z;
                    default: throw new IndexOutOfRangeException();
                }
            }
            set
            {
                switch (index)
                {
                    case 0: rotation.x = value; break;
                    case 1: rotation.y = value; break;
                    case 2: rotation.z = value; break;
                    case 3: rotation.w = value; break;
                    case 4: scale.x = value; break;
                    case 5: scale.y = value; break;
                    case 6: scale.z = value; break;
                    case 7: position.x = value; break;
                    case 8: position.y = value; break;
                    case 9: position.z = value; break;
                    default: throw new IndexOutOfRangeException();
                }
            }
        }
    }

    [ProtoContract]
    public class XTransform
    {
        [ProtoMember(1)]
        public XQuaternion rotation;

        [ProtoMember(2)]
        public XVector3 position;

        public float this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0: return rotation.x;
                    case 1: return rotation.y;
                    case 2: return rotation.z;
                    case 3: return rotation.w;
                    case 4: return position.x;
                    case 5: return position.y;
                    case 6: return position.z;
                    default: throw new IndexOutOfRangeException();
                }
            }
            set
            {
                switch (index)
                {
                    case 0: rotation.x = value; break;
                    case 1: rotation.y = value; break;
                    case 2: rotation.z = value; break;
                    case 3: rotation.w = value; break;
                    case 4: position.x = value; break;
                    case 5: position.y = value; break;
                    case 6: position.z = value; break;
                    default: throw new IndexOutOfRangeException();
                }
            }
        }
    }

    [ProtoContract]
    public class XMatrix4x4
    {
        [ProtoMember(1)]
        public XVector4 a;

        [ProtoMember(2)]
        public XVector4 b;

        [ProtoMember(3)]
        public XVector4 c;

        [ProtoMember(4)]
        public XVector4 d;
    }
}